package com.google.code.irouter.portal.server;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.code.irouter.model.Collector;
import com.google.code.irouter.model.Consumer;
import com.google.code.irouter.model.Guide;
import com.google.code.irouter.model.History;
import com.google.code.irouter.model.Model;
import com.google.code.irouter.model.Queue;
import com.google.code.irouter.model.Relationship;
import com.google.code.irouter.model.Solution;
import com.google.code.irouter.model.Transponder;
import com.google.code.irouter.portal.client.rpc.relation.RelationResult;
import com.google.code.irouter.portal.client.rpc.relation.RelationService;
import com.google.code.irouter.utils.ModelUtil;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

public class RelationServiceImpl extends RemoteServiceServlet implements
		RelationService {

	private static final long serialVersionUID = -5862570439720830660L;

	@Override
	public boolean save(String solutionId, String relationshipId, String name, List<Long> guideIdList,
			List<Long> consumerIdList) throws IllegalArgumentException {
		boolean result = true;
		try {
			if (solutionId == null)
				return false;
			Relationship relationship = new Relationship();
			Collector collector = new Collector();
			Transponder transponder = new Transponder();
			if(relationshipId != null) {
				Key relationshipKey = KeyFactory.createKey(
						Relationship.class.getSimpleName(), Long.valueOf(relationshipId));
				relationship = (Relationship) ModelUtil.select(Relationship.class, relationshipKey).get(0);
				Key collectorKey = KeyFactory.createKey(
						Collector.class.getSimpleName(), relationship.getCollector().getId());
				Key transponderKey = KeyFactory.createKey(
						Transponder.class.getSimpleName(), relationship.getTransponder().getId());
				collector = (Collector) ModelUtil.select(Collector.class, collectorKey).get(0);
				transponder = (Transponder) ModelUtil.select(Transponder.class, transponderKey).get(0);
				
			} else {
				Key solutionKey = KeyFactory.createKey(
						Solution.class.getSimpleName(), Long.valueOf(solutionId));
				relationship.setSolution(solutionKey);
			}
			relationship.setName(name);
			Set<Key> guideKeySet = new HashSet<Key>();
			Set<Key> consumerKeySet = new HashSet<Key>();
			for (Long id : guideIdList)
				guideKeySet.add(KeyFactory.createKey(
						Guide.class.getSimpleName(), id));
			for (Long id : consumerIdList)
				consumerKeySet.add(KeyFactory.createKey(
						Consumer.class.getSimpleName(), id));
			collector.setGuides(guideKeySet);
			transponder.setConsumers(consumerKeySet);
			relationship.setCollector(ModelUtil.save(collector).getKey());
			relationship.setTransponder(ModelUtil.save(transponder).getKey());
			ModelUtil.save(relationship);
		} catch (Exception exception) {
			result = false;
		}
		return result;
	}

	@Override
	public List<RelationResult> load(String id) throws IllegalArgumentException {
		List<RelationResult> result = null;
		try{
			Map<String, Object> query = new HashMap<String, Object>();
			query.put(
					"solution",
					KeyFactory.createKey(Solution.class.getSimpleName(),
							Long.valueOf(id)));
	
			List<Model> modelList = ModelUtil.select(Relationship.class, query);
			result = new ArrayList<RelationResult>();
			if(modelList.size() > 0) {				
				for (Model model : modelList) {
					Relationship relationship = (Relationship) model;
					int collector = 0;
					int transponder = 0;
					String solutionName = "";
					List<Model> collectorList = ModelUtil.select(Collector.class,
							relationship.getCollector());
					List<Model> transponderList = ModelUtil.select(Transponder.class,
							relationship.getTransponder());
					List<Model> solutionList = ModelUtil.select(Solution.class,
							relationship.getSolution());
					if (collectorList.size() > 0) {
						collector = ((Collector) collectorList.get(0)).getGuides()
								.size();
					}
					if (transponderList.size() > 0) {
						transponder = ((Transponder) transponderList.get(0))
								.getConsumers().size();
					}
					if (solutionList.size() > 0) {
						solutionName = ((Solution) solutionList.get(0)).getName();
					}
					RelationResult relationResult = new RelationResult();
					relationResult.setId(relationship.getKey().getId());
					relationResult.setName(relationship.getName());
					relationResult.setCollector(collector);
					relationResult.setTransponder(transponder);
					relationResult.setSolutionId(relationship.getSolution().getId());
					relationResult.setSolutionName(solutionName);
					result.add(relationResult);
				}
			}
		} catch (Exception exception) {
			// TODO
		}
		return result;
	}

	@Override
	public boolean remove(String[] ids) throws IllegalArgumentException {
		boolean result = true;
		try {
			List<Key> idList = new ArrayList<Key>();
			for(String id : ids) {
				Key key = KeyFactory.createKey(Relationship.class.getSimpleName(), Long.valueOf(id));
				List<Model> modellist = ModelUtil.select(Relationship.class, key);
				if(modellist.size() > 0) {
					Relationship relationship = (Relationship) modellist.get(0);
					Key keyCollector = relationship.getCollector();
					Key keyTransponder = relationship.getTransponder();
					if(keyCollector != null) {
						List<Model> collectorlist = ModelUtil.select(Collector.class, keyCollector);
						if(collectorlist.size() > 0)
							ModelUtil.remove((Collector) collectorlist.get(0));
					}
					if(keyTransponder != null) {
						List<Model> transponderlist = ModelUtil.select(Transponder.class, keyTransponder);
						if(transponderlist.size() > 0)
							ModelUtil.remove((Transponder) transponderlist.get(0));
					}
					
					Map<String, Object> query = new HashMap<String, Object>();
					query.put("relationship", relationship.getKey());
					List<Model> queueList = ModelUtil.select(Queue.class, query);
					for(Model model : queueList) {
						Queue queue = (Queue) model;
						List<Model> historyList = ModelUtil.select(History.class, queue.getHistory());
						if(historyList.size() > 0)
							ModelUtil.remove((History) historyList.get(0)); 
						ModelUtil.remove(queue); 
					}
				}
				idList.add(key);
			}
			ModelUtil.remove(idList);
		} catch (Exception exception) {
			// TODO
			result = false;
		}
		return result;
	}
}
